package ca.etsmtl.log430.lab3;

import java.util.Observable;

/**
 * This class registers students for courses.
 * 
 * @author A.J. Lattanze, CMU
 * @version 1.2, 2011-Feb-24
 */

/*
 * Modification Log **********************************************************
 * 
 * v1.2, R. Champagne, 2011-Feb-24 - Various refactorings, conversion of
 * comments to javadoc format.
 * 
 * v1.1, R. Champagne, 2002-Jun-19 - Adapted for use at ETS.
 * 
 * v1.0, A.J. Lattanze, 12/29/99 - Original version.
 * ***************************************************************************
 */
public class RegisterStudent extends Communication implements Runnable {
	boolean Stop = false;

	public RegisterStudent(Integer RegistrationNumber, String ComponentName) {
		super(RegistrationNumber, ComponentName);

	} // Constructor

	@Override
	public void update(Observable Thing, Object NotificationNumber) {
		Menus Menu = new Menus();
		// Displays Display = new Displays();
		Student MyStudent = new Student();
		Course MyCourse = new Course();

		// The update() method is an abstract method that is called whenever the
		// notifyObservers() method is called by the Observable class
		// First we check to see if the NotificationNumber is equal to this
		// thread's RegistrationNumber or SYSTEM_SHUT_DOWN. If they are, then we
		// execute - otherwise, we stay idle.

		if (registrationNumber.compareTo((Integer) NotificationNumber) == 0) {
			addToReceiverList("ListStudentsComponent");
			addToReceiverList("ListCoursesComponent");

			// Display the students and prompt the user to pick a student

			signalReceivers("ListStudentsComponent");

			MyStudent = Menu
					.pickStudent(CommonData.theListOfStudents.listOfStudents);

			if (MyStudent != null) {
				// Display the courses that are available and ask the user to
				// pick a
				// course to register for

				signalReceivers("ListCoursesComponent");

				MyCourse = Menu.pickCourse(CommonData.theListOfCourses
						.getListOfCourses());

				if (MyCourse != null) {
					// If the selected course and student exist, then complete
					// the
					// registration process.

					if (verifyCourseTake(MyStudent, MyCourse)) {
						if (courseValidation(MyStudent, MyCourse)) {
							MyCourse.register(MyStudent);
							MyStudent.register(MyCourse);
						}
					}

				} else {

					System.out.println("\n\n *** Course not found ***");

				} // if

			} else {

				System.out.println("\n\n *** Student not found ***");

			} // if

		} // if

		if (SYSTEM_SHUT_DOWN_ID.compareTo((Integer) NotificationNumber) == 0) {
			Stop = true;

		} // if

		removeFromReceiverList("ListCoursesComponent");
		removeFromReceiverList("ListStudentsComponent");

	} // update

	private boolean verifyCourseTake(Student student, Course course) {

		if (student.getCoursesTakenList().findCourse(course)) {
			System.out.println("\n *** This student is already in \""
					+ course.getCourseID() + ":" + course.getCourseName()
					+ "\" course  ***");
			System.out.println("Want to register anyway? (Yes/No)");
			Termio Terminal = new Termio();
			char UserChoice = ' ';
			UserChoice = Terminal.keyboardReadChar();

			if (UserChoice == 'Y' || UserChoice == 'y') {
				return true;
			} else {
				return false;
			}
		} else {
			return true;
		}

	}

	private boolean courseValidation(Student student, Course course) {

		if (student.getCoursesRegistered().findCourse(course)) {
			System.out.println("\n *** This student is already in \""
					+ course.getCourseID() + ":" + course.getCourseName()
					+ "\" course  ***");
			return false;

		}
		//

		// Validation conflit d horaire
		student.getCoursesRegistered().goToFrontOfList();
		Course courseRegistered;
		while ((courseRegistered = student.getCoursesRegistered()
				.getNextCourse()) != null) {

			boolean sameDay = false;

			boolean[] courseDays = { course.getDays().contains("L"),
					course.getDays().contains("MA"),
					course.getDays().contains("ME"),
					course.getDays().contains("J"),
					course.getDays().contains("V") };

			boolean[] courseRegisteredDays = {
					courseRegistered.getDays().contains("L"),
					courseRegistered.getDays().contains("MA"),
					courseRegistered.getDays().contains("ME"),
					courseRegistered.getDays().contains("J"),
					courseRegistered.getDays().contains("V") };

			// System.out.println("courseRegisteredDays");
			// for (int i = 0; i < courseRegisteredDays.length; i++) {
			// System.out.print(courseRegisteredDays[i] + " ");
			// }
			//
			// System.out.println("courseDays");
			// for (int i = 0; i < courseDays.length; i++) {
			// System.out.print(courseDays[i] + " ");
			// }

			for (int i = 0; i < courseRegisteredDays.length; i++) {
				if (courseRegisteredDays[i] && courseDays[i]) {
					sameDay = true;
				}
			}

			// System.out.println("SameDay");

			if (sameDay) {
				int courseStartTime = Integer.parseInt(course.getStartTime());
				int courseStopTime = Integer.parseInt(course.getStopTime());
				int crStartTime = Integer.parseInt(courseRegistered
						.getStartTime());
				int crStopTime = Integer.parseInt(courseRegistered
						.getStopTime());

				if ((courseStartTime >= crStartTime)
						&& (courseStartTime < crStopTime)
						|| (courseStopTime > crStartTime)
						&& (courseStopTime < crStopTime)
						|| (crStartTime >= courseStartTime)
						&& (crStartTime < courseStopTime)
						|| (crStopTime > courseStartTime)
						&& (crStopTime < courseStopTime)) {
					System.out
							.println("\n *** Course Schedule Conflicts. This student is already registered in:");
					System.out.println(courseRegistered.getCourseName() + " "
							+ courseRegistered.getCourseID() + " "
							+ courseRegistered.getSection() + " "
							+ courseRegistered.getDays() + " "
							+ courseRegistered.getStartTime() + ":"
							+ courseRegistered.getStopTime() + " "
							+ courseRegistered.getInstructor());
					System.out.println("  can't be registered to:");
					System.out.println(course.getCourseName() + " "
							+ course.getCourseID() + " " + course.getSection()
							+ " " + course.getDays() + " "
							+ course.getStartTime() + ":"
							+ course.getStopTime() + " "
							+ course.getInstructor());
					System.out.println(" ***");
					return false;
				}
			}
		}

		return true;
	}

	public void run() {
		System.out.println("\nListCourses Component Started...");

		try {
			while (!Stop) {

				Thread.sleep(1000);

			} // while

			System.out.println("\nListCourses Component Shutdown...");

		} catch (Exception e) {

			System.out.println("Exception occured in RegisterStudent.run(): "
					+ e);

		} // try-catch

	} // run
} // RegisterStudent